package cn.lavender.web.response.handler;

import cn.lavender.web.response.annotation.RestResponse;
import cn.lavender.web.response.api.ApiResponse;
import cn.lavender.web.response.entity.CommonConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.util.TypeUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>
 * 封装ResponseBody
 * </p>
 *
 * @author: zhu.chen
 * @date: 2021/3/29
 * @version: v1.0.0
 */
@Slf4j
@ControllerAdvice
public class ApiResponseHandler implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        RestResponse restResponse = (RestResponse) request.getAttribute(CommonConstant.API_TAG);
        return restResponse == null ? false : true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        // 若object是ApiResponse类型，则表示其是经过GlobalExceptionHandler(全局异常处理器)包装过的请求，则直接返回即可。
        if (TypeUtils.isAssignable(body.getClass(), ApiResponse.class)) {
            return body;
        }
        return ApiResponse.instanceSuccessApiResponse(body);
    }

}
